package com.apex.shared.core.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.experimental.UtilityClass;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * JSON工具类，基于Jackson库
 * 支持现代Java特性，如记录类型和密封类
 *
 * @author MoNaiHui
 */
@UtilityClass
public class JsonUtils {

    private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);

    // ---------------------- 对象转换 ----------------------

    /**
     * 对象转JSON字符串
     */
    public static String toJson(Object object) throws JsonProcessingException {
        return OBJECT_MAPPER.writeValueAsString(object);
    }

    /**
     * 对象转格式化的JSON字符串
     */
    public static String toPrettyJson(Object object) throws JsonProcessingException {
        return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
    }

    /**
     * JSON字符串转对象
     */
    public static <T> T fromJson(String json, Class<T> clazz) throws JsonProcessingException {
        return OBJECT_MAPPER.readValue(json, clazz);
    }

    /**
     * JSON字符串转List
     */
    public static <T> List<T> fromJsonList(String json, Class<T> clazz) throws JsonProcessingException {
        return OBJECT_MAPPER.readValue(json, new TypeReference<List<T>>() {});
    }

    /**
     * JSON字符串转Map
     */
    public static <K, V> Map<K, V> fromJsonMap(String json, Class<K> keyClass, Class<V> valueClass) throws JsonProcessingException {
        return OBJECT_MAPPER.readValue(json, OBJECT_MAPPER.getTypeFactory().constructMapType(Map.class, keyClass, valueClass));
    }

    // ---------------------- 节点操作 ----------------------

    /**
     * 解析JSON字符串为JsonNode
     */
    public static JsonNode parseNode(String json) throws JsonProcessingException {
        return OBJECT_MAPPER.readTree(json);
    }

    /**
     * 创建新的ObjectNode
     */
    public static ObjectNode createObjectNode() {
        return OBJECT_MAPPER.createObjectNode();
    }

    /**
     * 获取JsonNode中的值
     */
    public static String getNodeAsText(JsonNode node, String field, String defaultValue) {
        JsonNode fieldNode = node.get(field);
        return fieldNode != null && !fieldNode.isNull() ? fieldNode.asText() : defaultValue;
    }

    /**
     * 获取JsonNode中的整数值
     */
    public static int getNodeAsInt(JsonNode node, String field, int defaultValue) {
        JsonNode fieldNode = node.get(field);
        return fieldNode != null && !fieldNode.isNull() ? fieldNode.asInt() : defaultValue;
    }

    /**
     * 获取JsonNode中的布尔值
     */
    public static boolean getNodeAsBoolean(JsonNode node, String field, boolean defaultValue) {
        JsonNode fieldNode = node.get(field);
        return fieldNode != null && !fieldNode.isNull() ? fieldNode.asBoolean() : defaultValue;
    }

    // ---------------------- 类型转换 ----------------------

    /**
     * 对象转换为另一个类型
     */
    public static <T> T convert(Object fromValue, Class<T> toValueType) {
        return OBJECT_MAPPER.convertValue(fromValue, toValueType);
    }

    /**
     * 对象转换为复杂类型
     */
    public static <T> T convert(Object fromValue, TypeReference<T> toValueTypeRef) {
        return OBJECT_MAPPER.convertValue(fromValue, toValueTypeRef);
    }

    // ---------------------- 文件操作 ----------------------

    /**
     * 从文件读取JSON
     */
    public static <T> T readJsonFromFile(String filePath, Class<T> clazz) throws IOException {
        return OBJECT_MAPPER.readValue(FileUtils.readText(filePath), clazz);
    }

    /**
     * 写入JSON到文件
     */
    public static void writeJsonToFile(String filePath, Object object) throws IOException {
        FileUtils.writeText(filePath, toPrettyJson(object));
    }

    // ---------------------- 工具方法 ----------------------

    /**
     * 检查字符串是否为有效的JSON
     */
    public static boolean isValidJson(String json) {
        try {
            OBJECT_MAPPER.readTree(json);
            return true;
        } catch (JsonProcessingException e) {
            return false;
        }
    }

    /**
     * 合并两个JSON对象
     */
    public static JsonNode merge(JsonNode mainNode, JsonNode updateNode) {
        if (mainNode instanceof ObjectNode && updateNode instanceof ObjectNode) {
            ObjectNode mainObjectNode = (ObjectNode) mainNode;
            updateNode.fields().forEachRemaining(field -> 
                mainObjectNode.set(field.getKey(), field.getValue())
            );
        }
        return mainNode;
    }
} 